package research.persistence;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import research.entity.Entity;
import research.entity.EntityType;

public class EntityCache {
	private Map<EntityType, Set<Entity>> cache = null;

	public EntityCache() {
		super();
		cache = new HashMap<EntityType, Set<Entity>>();
	}
	
	private Set<Entity> getEntitiesByType(EntityType type) {
		if (!cache.containsKey(type))
			cache.put(type, new HashSet<Entity>());
		
		return cache.get(type);
	}
	
	public void add(Entity entity) {
		Set<Entity> entities = getEntitiesByType(entity.getType());
		if (entities.contains(entity))
			throw new PersistenceException("Adding of already exist entity");
		
		entities.add(entity);
	}
	
	public void remove(Entity entity) {
		Set<Entity> entities = getEntitiesByType(entity.getType());
		if (!entities.contains(entity))
			throw new PersistenceException("Removing of not exist entity");
		
		entities.remove(entity);
	}
	
	public void update(Entity entity) {
		Set<Entity> entities = getEntitiesByType(entity.getType());
		if (!entities.contains(entity))
			throw new PersistenceException("Update of not exist entity");
		
		Entity old = null;
		for (Entity stored : entities)
			if (stored == entity)
				old = stored;

		entities.remove(old);
		entities.add(entity);
	}
	
	public void add(Set<Entity> entities) {
		for (Entity entity : entities)
			add(entity);
	}
	
	public void remove(Set<Entity> entities) {
		for (Entity entity : entities)
			remove(entity);
	}
	
	public void update(Set<Entity> entities) {
		for (Entity entity : entities)
			update(entity);
	}
	
	public boolean contains(Entity entity) {
		if (!getEntitiesByType(entity.getType()).contains(entity))
			return false;
		
		return true;
	}
	
	public Entity get(Entity entity) {
		Set<Entity> entities = getEntitiesByType(entity.getType());
		for (Entity res : entities)
			if (res == entity)
				return res;

		return null;
	}
	
	public Set<Entity> getAll(EntityType type) {
		return getEntitiesByType(type);
	}
}
